<GenericConfirmationDialog
  {id}
  {label}
  {title}
  {positiveText}
  {confirmationButtonDisabled}
  on:positive="save()">
  <div class="word-filter-dialog">
    <div class="word-filter-keyword">
      <label for="word-filter-word-or-phrase" class="word-filter-keyword-label">
        <span>{intl.wordOrPhrase}</span>
        <!-- no need for aria-label="Required", the input is already marked as required -->
        <span aria-hidden="true" class="required">*</span>
      </label>
      <input type="text"
             required
             autocomplete="off"
             autocapitalize="off"
             on:input="onWordOrPhraseChange(event)"
             ref:wordInput
             id="word-filter-word-or-phrase"
      >
    </div>
    <div class="word-filter-expire-after" ref:expireSelectWrapper>
      <span class="word-filter-label-like word-filter-expire-label">{intl.expireAfter}</span>
      <Select className="word-filter-expiry-select"
              options={expiryOptions}
              defaultValue={expiryDefaultValue}
              on:change="onExpiryChange(event)"
              label="{intl.expireAfter}"
      />
    </div>
    <div class="word-filter-where-to-filter">
      <span class="word-filter-label-like" id="word-filter-where-to-filter-label">
        <span>{intl.whereToFilter}</span>
        <span aria-label="{intl.required}" class="required">*</span>
      </span>
      <ul class="word-filter-radio-list" aria-describedby="word-filter-where-to-filter-label" ref:contextCheckboxes>
        {#each filterContexts as context}
        <li>
          <input type="checkbox"
                 name="where-to-filter"
                 value={context.value}
                 on:change="onContextChange(event)"
                 id="where-to-filter-{context.value}">
          <label for="where-to-filter-{context.value}">{context.label}</label>
        </li>
        {/each}
      </ul>
    </div>
    <div class="word-filter-irreversible">
      <input type="checkbox"
             name="irreversible"
             ref:irreversibleCheckbox
             id="word-filter-irreversible">
      <label for="word-filter-irreversible">{intl.irreversible}</label>
    </div>
    <div class="word-filter-whole">
      <input type="checkbox"
             name="irreversible"
             ref:wholeWordCheckbox
             id="word-filter-whole">
      <label for="word-filter-whole">{intl.wholeWord}</label>
    </div>
  </div>
</GenericConfirmationDialog>
<style>
.word-filter-dialog {
  padding: 20px 40px;
  overflow-y: auto;
  display: grid;
  grid-template-areas: "keyword      expire"
                       "context      context"
                       "irreversible whole";
  grid-row-gap: 20px;
  grid-column-gap: 10px;
}
.word-filter-label-like {
  font-size: 1.3em;
}
.word-filter-radio-list {
  list-style: none;
  margin-top: 5px;
}
.word-filter-keyword {
  grid-area: keyword;
}
.word-filter-expire-after {
  grid-area: expire;
}
.word-filter-where-to-filter {
  grid-area: context;
}
.word-filter-irreversible {
  grid-area: irreversible;
}
.word-filter-whole {
  grid-area: whole;
}
.word-filter-keyword-label, .word-filter-expire-label {
  margin-right: 10px;
}
.required {
  color: var(--warn-color);
}
@media (max-width: 479px) {
  .word-filter-dialog {
    grid-template-areas: "keyword"
                         "expire"
                         "context"
                         "irreversible"
                         "whole";
    grid-column-gap: 5px;
    grid-row-gap: 10px;
  }
}
@media (max-width: 320px) {
  .word-filter-dialog {
    grid-row-gap: 5px;
  }
}
</style>
<script>
  import GenericConfirmationDialog from './GenericConfirmationDialog.html'
  import Select from '../../Select.html'
  import { show } from '../helpers/showDialog.js'
  import { close } from '../helpers/closeDialog.js'
  import { oncreate as onCreateDialog } from '../helpers/onCreateDialog.js'
  import { store } from '../../../_store/store.js'
  import {
    WORD_FILTER_CONTEXT_ACCOUNT,
    WORD_FILTER_CONTEXT_HOME,
    WORD_FILTER_CONTEXT_NOTIFICATIONS,
    WORD_FILTER_CONTEXT_PUBLIC,
    WORD_FILTER_CONTEXT_THREAD,
    WORD_FILTER_CONTEXTS,
    WORD_FILTER_EXPIRY_DEFAULT,
    WORD_FILTER_EXPIRY_OPTIONS
  } from '../../../_static/wordFilters.js'
  import { createOrUpdateFilter } from '../../../_actions/filters.js'

  export default {
    async oncreate () {
      onCreateDialog.call(this)
      this.syncFilterToDom(this.get().filter)
      this.computeConfirmationButtonDisabled()
    },
    store: () => store,
    data: () => ({
      filter: undefined,
      instanceName: undefined,
      positiveText: 'intl.save',
      expiryOptions: WORD_FILTER_EXPIRY_OPTIONS,
      expiryDefaultValue: WORD_FILTER_EXPIRY_DEFAULT,
      filterContexts: [
        {
          label: 'intl.filterHome',
          value: WORD_FILTER_CONTEXT_HOME
        },
        {
          label: 'intl.filterNotifications',
          value: WORD_FILTER_CONTEXT_NOTIFICATIONS
        },
        {
          label: 'intl.filterPublic',
          value: WORD_FILTER_CONTEXT_PUBLIC
        },
        {
          label: 'intl.filterThread',
          value: WORD_FILTER_CONTEXT_THREAD
        },
        {
          label: 'intl.filterAccount',
          value: WORD_FILTER_CONTEXT_ACCOUNT
        }
      ],
      confirmationButtonDisabled: false
    }),
    methods: {
      show,
      close,
      onWordOrPhraseChange (event) {
        this.computeConfirmationButtonDisabled()
      },
      onExpiryChange (event) {

      },
      onContextChange (event) {
        this.computeConfirmationButtonDisabled()
      },
      async save () {
        const filter = this.syncDomToFilter()
        const { instanceName } = this.get()
        await createOrUpdateFilter(instanceName, filter)
      },
      computeConfirmationButtonDisabled () {
        const confirmationButtonDisabled = !(this.refs.wordInput.value.replace(/\s+/g, '') &&
          [...this.refs.contextCheckboxes.querySelectorAll('input')].some(checkbox => checkbox.checked))
        this.set({ confirmationButtonDisabled })
      },
      syncFilterToDom (filter) {
        if (!filter) {
          filter = {
            phrase: '',
            expires_at: WORD_FILTER_EXPIRY_DEFAULT,
            context: [...WORD_FILTER_CONTEXTS],
            irreversible: false,
            whole_word: true
          }
        }

        this.refs.wordInput.value = filter.phrase

        let expiresAtValue = 0
        if (filter.expires_at) {
          const now = Date.now()
          expiresAtValue = WORD_FILTER_EXPIRY_OPTIONS.filter(_ => _.value)
            .sort((a, b) => {
              // expires_at is an absolute timestamp, so sort by whichever one is closest given the current datetime
              const aAbsoluteTime = now + (a.value * 1000)
              const bAbsoluteTime = now + (b.value * 1000)
              const aDelta = Math.abs(new Date(filter.expires_at).getTime() - aAbsoluteTime)
              const bDelta = Math.abs(new Date(filter.expires_at).getTime() - bAbsoluteTime)
              return aDelta < bDelta ? -1 : 1
            })[0].value
        }

        this.refs.expireSelectWrapper.querySelector('select').value = expiresAtValue
        for (const checkbox of [...this.refs.contextCheckboxes.querySelectorAll('input')]) {
          checkbox.checked = filter.context.includes(checkbox.value)
        }
        this.refs.irreversibleCheckbox.checked = !!filter.irreversible
        this.refs.wholeWordCheckbox.checked = !!filter.whole_word
      },
      syncDomToFilter () {
        const existingFilter = this.get().filter
        const filter = {
          id: existingFilter && existingFilter.id
        }
        filter.phrase = this.refs.wordInput.value
        const select = this.refs.expireSelectWrapper.querySelector('select')
        const selectValue = parseInt(select.value, 10)
        // When creating a new filter or updating a filter, `expires_in` is the number of seconds from now
        // that the filter expires. When reading, it's `expires_at` which is a string ISO timestamp.
        // Also, if you added a timeout for a filter, you can't change it to Never for some reason.
        filter.expires_in = selectValue || null
        filter.context = [...this.refs.contextCheckboxes.querySelectorAll('input')]
          .filter(input => input.checked)
          .map(input => input.value)
        filter.irreversible = this.refs.irreversibleCheckbox.checked
        filter.whole_word = this.refs.wholeWordCheckbox.checked

        return filter
      }
    },
    components: {
      GenericConfirmationDialog,
      Select
    }
  }
</script>
